define(function (require, exports, module) {
    'use strict';
    var $ = require('jquery'),
        _ = require('underscore'),
        notify = require('js/utils/notify');
    require('lib/plugins/validate/jquery.validate.min');
    require('lib/plugins/validate/i18n/messages_zh.min');
    require('paginator');
    require('confirm');
    require('multiselect');

    exports.numberWithCommas = function (x) {
        var parts = x.toString().split(".");
        parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        return parts.join(".");
    };
    exports.nearest10N = function (num) {
        var n10N = 10,
            multi = 10;
        while (num - n10N > 0) {
            n10N = n10N + multi;
            if (n10N / multi == 10) {
                multi = multi * 10;
            }
        }
        return n10N;
    };
    exports.getDeviceTypeStr = function (num) {
        num = parseInt(num);
        var dt = [];
        _.each(DEVICE_TYPE, function (value, key) {
            if (num & parseInt(key)) {
                dt.push(value);
            }
        });
        return dt.join(',');
    };
    exports.isIOS = function (t) {
        if (t & (2 | 16 | 32 | 64 | 128 | 256)) {
            return true;
        }
        return false;
    };
    exports.calcDeviceType = function (deviceTypes) {
        var deviceType = 0;
        if (deviceTypes) {
            _.each(deviceTypes, function (t) {
                deviceType |= parseInt(t);
            });
        }
        return deviceType;
    };
    exports.generateUUID = function () {
        var d = new Date().getTime();
        if (window.performance && typeof window.performance.now === "function") {
            d += performance.now(); //use high-precision timer if available
        }
        var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
        });
        return uuid;
    };
    exports.getValidator = function (selector) {
        var v = $(selector).validate({
            errorClass: "state-error",
            validClass: "state-success",
            errorElement: "em",
            highlight: function (element, errorClass, validClass) {
                $(element).addClass(errorClass).removeClass(validClass);
            },
            unhighlight: function (element, errorClass, validClass) {
                $(element).addClass(validClass).removeClass(errorClass);
            },
            errorPlacement: function (error, element) {
                if (element.is(":radio") || element.is(":checkbox")) {
                    element.closest('.option-group').after(error);
                } else if (element.is("select")) {
                    error.insertAfter(element.parent('div'));
                    return;
                } else {
                    error.insertAfter(element.parent());
                }
            }
        });
        return v;
    };
    exports.validElement = function (elem) {
        var $this = $(elem),
            val = exports.getInput(elem),
            isRight = true;
        if ($this.is('[required]') && (val === '' || val == undefined)) {
            isRight = false;
        } else if ($this.data("field") == "command" || $this.data("field") == "cmd" ||
            $(this).data('type') === 'command') {
            if (!val.match(/^cp:\/\/.*/)) {
                isRight = false;
            }
        } else if ($this.attr("min") || $this.attr("max")) {
            val = parseInt(val);
            var min = parseInt($this.attr("min")),
                max = parseInt($this.attr("max"));
            if (min && val < min) isRight = false;
            if (max && val > max) isRight = false;
        } else if ($this.attr("maxlength") || $this.attr("minlength")) {
            var maxlength = $this.attr('maxlength'),
                minlength = $this.attr('minlength');
            if (maxlength && val.length > maxlength) isRight = false;
            if (minlength && val.length < minlength) isRight = false;
        }
        return isRight;
    };
    exports.multiselect = function (selector, searchable, options) {
        if (!options) options = {};
        if (searchable) {
            options.enableFiltering = true;
            options.enableCaseInsensitiveFiltering = true;
            options.maxHeight = 250;
        }
        var defaultOptions = {
            buttonWidth: '100%',
            allSelectedText: '已全选',
            numberDisplayed: 3,
            nonSelectedText: '请选择',
            nSelectedText: '项已选择',
            selectAllText: '全选',
        }
        _.each(defaultOptions, function (v, k) {
            if (options[k] === undefined) {
                options[k] = v;
            }
        });
        $(selector).multiselect(options);
    };
    exports.simpleCheck = function (selector) {
        var inputAllRight = true;
        if (!selector) selector = 'body';
        $(selector).find('[required]').not('.placeholder').each(function () {
            if (!exports.validElement(this)) {
                inputAllRight = false;
                $(this).removeClass("state-success").addClass("state-error");
            }
        });
        return inputAllRight;
    };
    exports.renderTable = function (tableId, options) {
        var orderby = options.$orderby,
            desc = false;
        if (orderby && orderby[0] == '-') {
            desc = true;
            orderby = orderby.substr(1);
        }
        var selectorPrefix = '#' + tableId + ' ';
        $(selectorPrefix + 'span.fa').remove();
        $(selectorPrefix + 'th.sortable').append(' <span class="fa fa-sort deactive"></span>');
        var iconClass = desc ? "fa-sort-desc" : "fa-sort-asc";
        $(selectorPrefix + 'th[data-field=' + orderby + '] span').removeClass('fa-sort deactive').addClass(iconClass);
        $(selectorPrefix + 'th.sortable').click(function () {
            var field = $(this).data('field');
            var desc = $(this).children('span').hasClass('fa-sort-asc');
            if (desc) field = '-' + field;
            if (options.sortCallback) {
                options.sortCallback(field);
            }
        });
    };
    exports.getPaginator = function (options, total, url_prefix) {
        var pageSize = options.$size || PAGE_SIZE,
            currentPage = options.$page || 1,
            start = (currentPage - 1) * pageSize + 1,
            end = start + pageSize - 1,
            totalPages = Math.ceil(total / pageSize) || 1;
        if (end > total) end = total;
        $('#page-tips').text("第" + start + "到第" + end + "项, 共" + total + "项");
        $('#paginator').bootstrapPaginator({
            currentPage: currentPage,
            totalPages: totalPages,
            numberOfPages: 10,
            alignment: 'center',
            itemTexts: function (type, page, current) {
                switch (type) {
                    case "first":
                        return "首页";
                    case "prev":
                        return "前一页";
                    case "next":
                        return "后一页";
                    case "last":
                        return "尾页";
                    case "page":
                        return page;
                }
            },
            onPageClicked: function (e, originalEvent, type, page) {
                options.$page = page;
                location.href = exports.composeQueryString(url_prefix, options);
            },
        });
        $('#paginator').append('<input id="pageNumber" type="text" class="pull-right" size="2">');
        $('#pageNumber').val(currentPage);
        $('#pageNumber').off().on('keypress', function (e) {
            if (e.which == 13) {
                e.stopImmediatePropagation();
                var page = parseInt($('#pageNumber').val());
                if (!isNaN(page) && page <= totalPages) {
                    options.$page = page;
                    location.href = exports.composeQueryString(url_prefix, options);
                }
            }
        })
    };
    //一次性替换
    exports.loadTemplates = function (clses, callback) {
        var deferreds = [];
        _.each(clses, function (cls, index) {
            _.each(cls, function (view) {
                if (view.prototype.template) {
                    deferreds.push($.get('templates/' + view.prototype.template, function (data) {
                        view.prototype.template = _.template(data);
                    }));
                }
            });
        });
        $.when.apply(null, deferreds).done(callback);
    };

    //惰性替换
    exports.loadTemplate = function (view, callback, sync) {
        var temp = view.prototype.template;
        if (temp != undefined && typeof temp !== 'function') {
            $.ajax({
                url: 'templates/' + temp,
                async: sync ? false: true,
                success: function (data) {
                    view.prototype.template = _.template(data);
                    if (callback) callback();
                },
                fail: function () {
                    console.log('template not exist');
                }
            });
        } else if (temp != null && callback != null) {
            callback();
        }
    };
    exports.parseQueryString = function (queryString) {
        var params = {};
        if (queryString) {
            _.each(
                _.map(decodeURI(queryString).split(/&/g), function (el, i) {
                    var aux = el.split('='),
                        o = {};
                    if (aux.length >= 1) {
                        var val = null;
                        if (aux.length == 2)
                            val = aux[1];
                        o[aux[0]] = val;
                    }
                    return o;
                }),
                function (o) {
                    _.extend(params, o);
                }
            );
        }
        return params;
    };
    exports.composeQueryString = function (base, queryDict) {
        if ($.isEmptyObject(queryDict)) return base;
        base += '?';
        _.each(queryDict, function (value, key) {
            if (value === true) {
                value = 1;
            } else if (value === false) {
                value = 0;
            }
            if (value != undefined) {
                if (typeof (value) == 'object') {
                    base += key + '=' + JSON.stringify(value) + '&';
                } else {
                    base += key + '=' + value + '&';
                }
            } else {
                base += key + '&';
            }
        });
        base = base.slice(0, -1);
        return base;
    };
    exports.saveSearched = function (key, searched) {
        var k = key + '_searched';
        localStorage[k] = JSON.stringify(searched);
    };
    exports.clearSearched = function (key) {
        if (key) {
            delete localStorage[key + '_searched'];
        } else {
            // NOTE: TAKE CARE
            localStorage.clear();
        }
    };
    exports.getSearched = function (key) {
        var t = localStorage[key + '_searched'] || '{}';
        return JSON.parse(t);
    };
    exports.snapPage = function (key) {
        var k = key + '_' + 'style',
            style = {};
        if ($('body').hasClass('sb-r-o')) {
            style.sbr = 'sb-r-o';
        } else {
            style.sbr = 'sb-r-c';
        }
        localStorage[k] = JSON.stringify(style);
    };
    //左边栏状态
    exports.setls = function (status) {
        return $('body').removeClass('sb-l-c sb-l-o sb-l-m').addClass('sb-l-' + status);
    };
    //右边栏状态
    exports.setrs = function (status) {
        return $('body').removeClass('sb-r-o sb-r-c').addClass('sb-r-' + status);
    };
    exports.getCurrentKey = function () {
        var hash = location.hash.split('/');
        if (hash[hash.length - 1] == '' || hash[hash.length - 1][0] == "?") {
            hash = hash.slice(0, hash.length - 1);
        }
        hash = hash.join('/');
        return hash.slice(1, hash.length);   //remove #
    };
    exports.getInput = function (elem, forSearch) {
        var $this = $(elem),
            value = null;
        if ($this.data('value')) {
            value = $this.data('value')
        } else if ($this.is('img')) {
            value = $this.attr('src')
        } else if ($this.is(':checkbox')) {
            value = $this.is(':checked');
        } else {
            var val = $this.val(),
                type = $this.data('type'),
                convert = null;
            if ($this.is('select') && val == null)return null;
            if (type == 'int') convert = parseInt;
            else if (type == 'float') convert = parseFloat;
            if ($.isArray(val)) {
                if (convert != null) {
                    for (var i = 0; i < val.length; ++i) val[i] = convert(val[i]);
                }
                if (val.length == 1 && forSearch) {
                    value = val[0];
                } else if (forSearch) {
                    value = {
                        '$in': val
                    };
                } else {
                    value = val;
                };
            } else if (convert != null) {
                if (!val) return '';            //特殊处理，表示什么都没填
                value = convert(val);
                if (isNaN(value)) value = null;
            } else {
                value = val;
            }
        }
        return value;
    };
    exports.getAllInput = function (selector, forSearch) {
        var inputs = {};
        if (selector == undefined) selector = "body";
        $(selector).find('[data-field]').each(function () {
            var $this = $(this),
                key = $this.data('field'),
                value = exports.getInput(this, forSearch),
                keyArray = key.split('.'),
                useless = $this.data('useless'),
                t = inputs;
            if ($this.is('select') && value == null) {
                if (!forSearch) value = [];
                else return;
            }
            if (useless != undefined && value == useless) return;
            if ($this.hasClass('placeholder')) return;
            var parent = inputs;
            for (var i = 0; i < keyArray.length - 1; ++i) {
                var key = keyArray[i];
                if (parent[key] == undefined) {
                    parent[key] = {};
                }
                parent = parent[key];
            }
            parent[keyArray[keyArray.length - 1]] = value;
        });
        return inputs;
    };
    exports.humanizeContent = function (resource, content) {
        content = JSON.parse(content || '{}');
        var result = '';
        if (content && content.extend) {
            if (typeof content.extend == "string") content.extend = JSON.parse(content.extend);
            $.extend(content, content.extend);
            delete content.extend;
        }
        _.each(content, function (v, k) {
            if (v == null || v == '') return;
            if (k == 'id' || k == 'created_at' || k == 'updated_at') return;
            if (k == 'status') {
                if (resource == 'awarded_order') result += ('订单状态 -> ' + ORDER_STATUS[v] + ', ');
                else if (resource == 'template') result += ('状态 -> ' + TEMPLATE_STATUS[v] + ', ');
            } else if (k == 'ship_status') {
                result += ('发货状态 -> ' + SHIP_STATUS[v] + ', ');
            } else {
                result += (k + ' -> ' + v + ', ');
            }
        })
        result = result.slice(0, -2);
        return result;
    };

    exports.exportData = function (base, options) {
        options.$size = -1;
        delete options.$page;
        delete options.$orderby;
        options.$export = true;
        $.get(exports.composeQueryString(base, options)).done(function (resp) {
            window.location = resp.data.url;
        }).fail(function (resp) {
            notify.error();
        });
    };

    exports.deleteItem = function (e, collection) {
        var itemId = $(e.currentTarget).closest('tr').data('id'),
            item = collection.get(itemId);
        $.confirm({
            title: '确认操作',
            content: '确认删除ID为' + itemId + '的项么？',
            confirmButton: '确认',
            cancelButton: '取消',
            icon: 'fa fa-warning',
            theme: 'bootstrap',
            backgroundDismiss: true,
            keyboardEnabled: true,
            confirmButtonClass: 'btn-danger',
            confirm: function () {
                item.destroy({
                    success: function () {
                        notify.success();
                    },
                    error: function (m, r) {
                        notify.notifyResp(r);
                    },
                    wait: true
                });
            },
        });
    };


});
